package z.t.b.db.meta;

import org.apache.commons.lang3.StringUtils;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

/**
 * xx
 *
 * @Description TODO
 * @Author ztb
 * @Date 2024/3/23 16:59
 * @Version 1.0
 */
public class DB implements AutoCloseable {

    private String schema;
    private String charset;
    private String dbType;
    private String username;
    private String password;
    private String hostname;
    private int port;
    private String driverClass;
    private String jdbcUrl;
    /**
     * 待处理表，如果是空就处理所有的表
     */
    private List<String> tableList = new ArrayList<>();
    private Map<String, Table> tables;
    private Connection conn;
    private MetadataLoader metadataLoader;

    public DB() {
        tables = new TreeMap<>();
    }

    public void init(){
        if(StringUtils.isBlank(dbType)){
            throw new IllegalArgumentException("参数错误：数据库类型不能为空");
        }
        if(StringUtils.isBlank(schema)){
            throw new IllegalArgumentException("参数错误：数据库模式不能为空");
        }
        if(StringUtils.isBlank(username)){
            throw new IllegalArgumentException("参数错误：用户不能为空不能为空");
        }
        if(StringUtils.isBlank(jdbcUrl)){
            throw new IllegalArgumentException("参数错误：jdbcUrl不能为空");
        }
        this.createConnection();
        this.metadataLoader = MetadataLoaderFactory.getMetadataLoader(dbType);
        try {
            this.metadataLoader.loadTablesFromDB(this);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     *
     */
    private DB createConnection(){
        try{
            if(StringUtils.isNotBlank(driverClass)){
                Class.forName(driverClass);
            }
            conn = DriverManager.getConnection(jdbcUrl, username, password);
        }catch (Exception e){
            e.printStackTrace();
        }
        return this;
    }

    public Map<String, Table> getTables() {
        return tables;
    }

    public DB setTables(Map<String, Table> tables) {
        this.tables = tables;
        return this;
    }

    public DB addTable(Table table){
        this.tables.put(table.getTableName(), table);
        return this;
    }

    public Table getTable(String tableName){
        return this.tables.get(tableName);
        /*Table table = this.tables.get(tableName);
        if(table != null){
            return table;
        }
        // 如果代处理列表不为空，且表不在列表，则直接返回空
        if(tableList.size()>0 && !tableList.contains(tableName)){
            return null;
        }
        // 初始化表/试图信息
        table = this.initTable(tableName);
        if(table != null){
            this.addTable(table);
        }
        return table;*/
    }

    /**
     *
     * @param tableName
     * @return
     */
    private Table initTable(String tableName){
        try {
            // 加载表信息
            Table table = this.metadataLoader.loadTableFromDB(this, tableName);
            // 加载列信息
            this.metadataLoader.loadColumnsByTable(table);
            // 加载索引信息
            this.metadataLoader.loadKeysByTable(table);
            // 加载建表sql
            this.metadataLoader.getCreateDDL(table);
            return table;
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    public String getSchema() {
        return schema;
    }

    public DB setSchema(String schema) {
        this.schema = schema;
        return this;
    }

    public String getCharset() {
        return charset;
    }

    public DB setCharset(String charset) {
        this.charset = charset;
        return this;
    }

    public String getDbType() {
        return dbType;
    }

    public DB setDbType(String dbType) {
        this.dbType = dbType;
        return this;
    }

    public String getUsername() {
        return username;
    }

    public DB setUsername(String username) {
        this.username = username;
        return this;
    }

    public String getPassword() {
        return password;
    }

    public DB setPassword(String password) {
        this.password = password;
        return this;
    }

    public String getHostname() {
        return hostname;
    }

    public DB setHostname(String hostname) {
        this.hostname = hostname;
        return this;
    }

    public int getPort() {
        return port;
    }

    public DB setPort(int port) {
        this.port = port;
        return this;
    }

    public String getDriverClass() {
        return driverClass;
    }

    public DB setDriverClass(String driverClass) {
        this.driverClass = driverClass;
        return this;
    }

    public String getJdbcUrl() {
        return jdbcUrl;
    }

    public DB setJdbcUrl(String jdbcUrl) {
        this.jdbcUrl = jdbcUrl;
        return this;
    }

    public List<String> getTableList() {
        return tableList;
    }

    public void setTableList(List<String> tableList) {
        this.tableList = tableList;
    }

    public Connection getConn() {
        return conn;
    }

    @Override
    public void close() throws Exception {
        if(this.conn != null && !this.conn.isClosed()){
            this.conn.close();
        }
    }

    @Override
    protected void finalize() throws Throwable {
        super.finalize();
        if(this.conn != null && !this.conn.isClosed()){
            this.conn.close();
        }
    }
}
